home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Applications / Graphics / MapMaker / Source / InputView.m < prev    next >
Text File  |  1990-12-08  |  11KB  |  512 lines

  1.  
  2.  
  3. /* Generated by Interface Builder */
  4.  
  5. #import "InputView.h"
  6. #import "ControlObject.h"
  7. #import <appkit/appkit.h>
  8. #import <math.h>
  9. #import "constants.h"
  10. #import "pointdata.h"
  11.  
  12.  
  13. void doIMapping(PointList *p)
  14. {
  15.     int t;
  16.     Point *pt;
  17.     int lastpen = UP;
  18.     float lastcol = NX_LTGRAY;
  19.  
  20.     PSsetgray(NX_LTGRAY);
  21.     PSsetlinewidth(0.0);
  22.     for(t=gotoPointInList(p,0,&pt);(t);t=gotoNextPointInList(p,&pt)) {
  23.         if (lastpen == DOWN)
  24.             PSlineto(pt->x,pt->y);
  25.         else
  26.             PSmoveto(pt->x,pt->y);
  27.         if (lastcol != pt->pencolour) {
  28.             PSstroke();
  29.             PSnewpath();
  30.             PSmoveto(pt->x,pt->y);
  31.             PSsetgray(pt->pencolour);
  32.         }
  33.         lastpen = pt->pen;
  34.         lastcol = pt->pencolour;
  35.     }
  36.     PSstroke();
  37. }
  38.  
  39. float AngleBetween(Point *pa, Point *pb, Point *p)
  40. {
  41.     Point v1,v2;
  42.     float f;
  43.     v1.x = pa->x - p->x;
  44.     v1.y = pa->y - p->y;
  45.     v2.x = pb->x - p->x;
  46.     v2.y = pb->y - p->y;
  47.     f = ((v1.x * v2.x) + (v1.y * v2.y));
  48.     if (f == 0.0)
  49.         return (PI/2);
  50.     return fabs(acos(f/sqrt(fabs(f))));
  51. }
  52.  
  53. @implementation InputView
  54.  
  55. - (BOOL)gridState
  56. {
  57.     return GridOn;
  58. }
  59.  
  60. - setGridState:(BOOL)newGridState
  61. {
  62.     GridOn = newGridState;
  63.     return self;
  64. }
  65.  
  66. - setItUp:sender
  67. {
  68.     caller = sender;
  69.     inputMode = [sender inputMode];
  70.     inputX = [sender inputX];
  71.     inputY = [sender inputY];
  72.     inputPen = [sender inputPen];
  73.     [self setDrawSize:(IRight-ILeft) :(ITop-IBottom)];
  74.     [self setDrawOrigin:ILeft :IBottom];
  75.     [[self window] addToEventMask:
  76.                             NX_LMOUSEDRAGGEDMASK|NX_MOUSEMOVEDMASK|NX_FLAGSCHANGEDMASK];
  77.     [[self window] makeFirstResponder:self];
  78.     instanceDrawing = NO;
  79.     state = WAITING;
  80.     newPointList(¤tPoints);
  81.     return self;
  82. }
  83.  
  84. - drawGrid
  85. {
  86.     float f;
  87.     for(f=ILeft;(f<=IRight);f=f+(PI/12)) {
  88.         PSmoveto(f,ITop);
  89.         PSlineto(f,IBottom);
  90.     }
  91.     for(f=0.0;(f<=ITop);f=f+(PI/12)) {
  92.         PSmoveto(ILeft,f);
  93.         PSlineto(IRight,f);
  94.     }
  95.     for(f=0.0;(f>=IBottom);f=f-(PI/12)) {
  96.         PSmoveto(ILeft,f);
  97.         PSlineto(IRight,f);
  98.     }
  99.     return self;
  100. }
  101.  
  102. - drawSelf:(const NXRect *)rects :(int)rectCount
  103. {
  104.     if (instanceDrawing) {
  105.         PSsetinstance(YES);
  106.         [self doInstanceDragSwitch];
  107.     } else {
  108.         PSsetinstance(NO);
  109.         NXEraseRect(&bounds);
  110.         PSsetgray(NX_LTGRAY);
  111.         PSsetlinewidth(0.0);
  112.         if (GridOn == YES)
  113.             [self drawGrid];
  114.         doIMapping(¤tPoints);
  115.     }
  116.     return self;
  117. }
  118.  
  119. -saveFile
  120. {
  121.     if (!savePanel) {
  122.         savePanel = [SavePanel new];
  123.         [savePanel setRequiredFileType:"map"];
  124.     }
  125.     if ([savePanel runModal])
  126.         if (savePointList(¤tPoints,(char *)[savePanel filename]))
  127.             return self;
  128.         else
  129.             NXRunAlertPanel("File System Error.","MapMaker couldn't save your map.",NULL,NULL,NULL);
  130.     else
  131.         return self;
  132. }
  133.  
  134. - openFile:(const char *)filename
  135. {
  136.     freePointList(¤tPoints);
  137.     newPointList(¤tPoints);
  138.     if (!(loadPointList(¤tPoints,(char *)filename)))
  139.         NXRunAlertPanel("File System Error.","MapMaker couln't load %s.",NULL,NULL,NULL,filename);
  140.     [caller getNewInput];
  141.     [caller refreshOutput];
  142.     [self display];
  143.     return self;
  144. }
  145.  
  146. -openFile
  147. {    
  148.     if (!openPanel) {
  149.         openPanel = [OpenPanel new];
  150.         [openPanel setRequiredFileType:"map"];
  151.     }
  152.     if ([openPanel runModal]) {
  153.         [self openFile:[openPanel filename]];
  154.     }
  155.     return self;
  156. }
  157.  
  158. -clearFile
  159. {
  160.     freePointList(¤tPoints);
  161.     newPointList(¤tPoints);
  162.     [self display];
  163.     [caller getNewInput];
  164.     [caller refreshOutput];
  165.     return self;
  166. }
  167.  
  168. - map:(PointList **)pl
  169. {
  170.     *pl = ¤tPoints;
  171.     return self;
  172. }
  173.  
  174. - mouseDown:(NXEvent *)theEvent
  175. {
  176.     location = &(theEvent->location);
  177.     switch (state) {
  178.         case DELETING :     instanceDrawing = YES;
  179.                         [self display];
  180.                         break;
  181.         case INSERTING : [self insertPoint:theEvent];
  182.                         state = DMOVING;
  183.                         MoveIndex = InsertIndex;
  184.                         [self display];
  185.                         break;
  186.         case MOVING :    instanceDrawing = YES;
  187.                         [self display];
  188.                         break;
  189.         default :    instanceDrawing = YES;
  190.                 [self display];
  191.                 break;
  192.     }
  193.     return self;
  194. }
  195.  
  196. - mouseUp:(NXEvent *)theEvent
  197. {
  198.     switch (state) {
  199.         case DELETING :
  200.                     [self deletePoint:theEvent];
  201.                     instanceDrawing = NO;
  202.                     [self display];
  203.                     break;
  204.         case INSERTING :
  205.                     instanceDrawing = NO;
  206.                     [self display];
  207.                     break;
  208.         case MOVING :  break;
  209.         case DMOVING :
  210.                     [self movePoint:theEvent];
  211.                     instanceDrawing = NO;
  212.                     [self display];
  213.                     [self fixState:theEvent];
  214.                     break;
  215.         default :        [self addPoint:theEvent];
  216.                     instanceDrawing = NO;
  217.                     [self display];
  218.                     break;
  219.     }
  220.     return self;
  221. }
  222.  
  223. - insertPoint:(NXEvent *)theEvent
  224. {
  225.     NXPoint pt;
  226.     Point p,*p1,*p2,*p3;
  227.     int s,t,u;
  228.     float f,g;
  229.     
  230.     pt = theEvent->location;
  231.     [self convertPoint:&pt fromView:nil];
  232.     p.x = pt.x;
  233.     p.y = pt.y;
  234.     p.pen = DOWN;
  235.     p.pencolour = NX_BLACK;
  236.     if (theEvent->flags&NX_ALTERNATEMASK) 
  237.         p.pen = UP;
  238.     s = gotoPointInList(¤tPoints,InsertIndex-1,&p1);
  239.     if (s)
  240.         t = gotoNextPointInList(¤tPoints,&p2);
  241.     else
  242.         t = gotoPointInList(¤tPoints,InsertIndex,&p2);
  243.     if (t)
  244.         u = gotoNextPointInList(¤tPoints,&p3);
  245.     else
  246.         u = gotoPointInList(¤tPoints,InsertIndex+1,&p3);
  247.     if ((s) && (t) && (u)) {
  248.         f = AngleBetween(p1,&p,p2);
  249.         g = AngleBetween(p3,&p,p2);
  250.         if (f > g) {
  251.             InsertIndex++;
  252.         }
  253.     } else if ((s) && (t)) {
  254.         f = AngleBetween(p1,&p,p2);
  255.         if (f > (PI/2)) {
  256.             InsertIndex++;
  257.         }
  258.     } else if ((t) && (u)) { 
  259.         f = AngleBetween(p3,&p,p2);
  260.         if (f <= (PI/2)) {
  261.             InsertIndex++;
  262.         }
  263.     }  else {
  264.         InsertIndex = 0;
  265.     }
  266.     /* find slopes. */
  267.         
  268.     s= insertInPointListAt(¤tPoints,&p,InsertIndex);
  269.     return self;
  270. }
  271.  
  272. - movePoint:(NXEvent *)theEvent
  273. {
  274.     NXPoint pt;
  275.     Point *p;
  276.     int s;
  277.     
  278.     pt = theEvent->location;
  279.     [self convertPoint:&pt fromView:nil];
  280.     s = gotoPointInList(¤tPoints,MoveIndex,&p);
  281.     p->x = pt.x;
  282.     p->y = pt.y;
  283.     return self;
  284. }
  285.  
  286. - addPoint:(NXEvent *)theEvent
  287. {
  288.     NXPoint pt;
  289.     Point p;
  290.  
  291.     pt = theEvent->location;
  292.     [self convertPoint:&pt fromView:nil];
  293.  
  294.     p.x = pt.x;
  295.     p.y = pt.y;
  296.     p.pen = DOWN;
  297.     p.pencolour = NX_BLACK;
  298.     if (theEvent->flags&NX_ALTERNATEMASK) 
  299.         p.pen = UP;
  300.         
  301.     addToPointList(¤tPoints,&p);
  302.     return self;
  303. }
  304.  
  305. - deletePoint:(NXEvent *)theEvent
  306. {
  307.     int s,index;
  308.     NXPoint pt;
  309.     Point *p;
  310.  
  311.     pt = theEvent->location;
  312.     [self convertPoint:&pt fromView:nil];
  313.  
  314.     s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
  315.     if ((!s) ||  ((POINTRADIUS * POINTRADIUS) <  (((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y)))))
  316.         return self;
  317.     removeFromPointList(¤tPoints,index);
  318.     return self;
  319. }
  320.  
  321. - doInstanceDragSwitch
  322. {
  323.     NXPoint pt;
  324.     Point *p, *p1,*p2, *p3;
  325.     int s,t,u;
  326.     int index;
  327.     int hold1,hold2;
  328.     
  329.     pt = *location;
  330.     [self convertPoint:&pt fromView:nil];
  331.     
  332.     switch(state) {
  333.         case DELETING :
  334.                 s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
  335.                 if ((!s) ||  ((POINTRADIUS * POINTRADIUS) < 
  336.                             (((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y)))))
  337.                     {
  338.                     PSnewinstance();
  339.                     break;
  340.                 }
  341.                 PSsetgray(NX_BLACK);
  342.                 PSsetlinewidth(0.0);
  343.                 PSnewinstance();
  344.                 PSarc(p->x,p->y,POINTRADIUS,(2*PI),PI);
  345.                 PSstroke();
  346.                 break;
  347.         case INSERTING :
  348.                 s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
  349.                 if ((!s) || ((POINTRADIUS * POINTRADIUS) < 
  350.                             (((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y))))) {
  351.                     PSnewinstance();
  352.                     break;
  353.                 }
  354.                 InsertIndex = index;
  355.                 PSsetgray(NX_BLACK);
  356.                 PSsetlinewidth(0.0);
  357.                 PSnewinstance();
  358.                 PSarc(pt.x,pt.y, POINTRADIUS,(2*PI),PI);
  359.                 PSstroke();
  360.                 break;
  361.         case MOVING :
  362.                 s = nearestPointInList(¤tPoints,&p,pt.x,pt.y,&index);
  363.                 if ((!s) || ((POINTRADIUS * POINTRADIUS) < 
  364.                             (((pt.x - p->x) * (pt.x - p->x)) + ((pt.y - p->y) * (pt.y - p->y)))))
  365.                     {
  366.                     PSnewinstance();
  367.                     break;
  368.                 }
  369.                 MoveIndex = index;
  370.                 PSsetgray(NX_BLACK);
  371.                 PSsetlinewidth(0.0);
  372.                 PSnewinstance();
  373.                 PSarc(p->x,p->y,POINTRADIUS,(2*PI),PI);
  374.                 PSstroke();
  375.                 break;
  376.         case DMOVING :
  377.                 s =gotoPointInList(¤tPoints,MoveIndex-1,&p2);
  378.                 if (s)
  379.                     u = gotoNextPointInList(¤tPoints,&p1);
  380.                 else
  381.                     u = gotoPointInList(¤tPoints,MoveIndex,&p1);
  382.                 if (u)
  383.                     t = gotoNextPointInList(¤tPoints,&p3);
  384.                 else
  385.                     t = gotoPointInList(¤tPoints,MoveIndex+1,&p3);
  386.                 PSsetgray(NX_BLACK);
  387.                 PSsetlinewidth(0.0);
  388.                 PSnewinstance();
  389.                 if ((s) && (p2->pen == DOWN)) {
  390.                     PSsetgray(NX_BLACK);
  391.                     PSmoveto(p2->x,p2->y);
  392.                     PSlineto(pt.x,pt.y);
  393.                 } else {
  394.                     PSmoveto(pt.x,pt.y);
  395.                 }
  396.                 if ((t) && (u) && (p1->pen == DOWN)) {
  397.                     PSlineto(p3->x,p3->y);
  398.                 }
  399.                 PSstroke();
  400.                 break;
  401.         default :    s = lastPointInList(¤tPoints,&p);
  402.                 if ((!s) || (p->pen == UP)) return self;
  403.                 PSsetgray(NX_BLACK);
  404.                 PSsetlinewidth(0.0);
  405.                 PSnewinstance();
  406.                 PSmoveto(p->x,p->y);
  407.                 PSlineto(pt.x,pt.y);
  408.                 PSstroke();
  409.                 break;
  410.     }
  411.     return self;
  412. }
  413.  
  414. - mouseDragged:(NXEvent *)theEvent
  415. {
  416.     NXPoint pt;
  417.     char str[20];
  418.     
  419.     pt = *location;
  420.     [self convertPoint:&pt fromView:nil];
  421.     
  422.     sprintf(str,"%.1f",(pt.x)*(180/PI));
  423.     [inputX setStringValue:str];
  424.     sprintf(str,"%.1f",(pt.y)*(180/PI));
  425.     [inputY setStringValue:str];
  426.  
  427.     switch (state) {
  428.         case DELETING :    
  429.                         location = &(theEvent->location);
  430.                         [self display];
  431.                         break;
  432.         case INSERTING : ;
  433.         case MOVING : state = DMOVING;
  434.         case DMOVING : location = &(theEvent->location);
  435.                         [self display];
  436.                         break;
  437.         default:    location = &(theEvent->location);
  438.                  [self display];
  439.                  break;
  440.     }
  441.     return self;
  442. }
  443.  
  444. - mouseMoved:(NXEvent *)theEvent
  445. {
  446.     NXPoint pt;
  447.     char str[20];
  448.     
  449.     pt = theEvent->location;
  450.     [self convertPoint:&pt fromView:nil];
  451.     
  452.     sprintf(str,"%.1f",(pt.x)*(180/PI));
  453.     [inputX setStringValue:str];
  454.     sprintf(str,"%.1f",(pt.y)*(180/PI));
  455.     [inputY setStringValue:str];
  456.     
  457.     switch (state) {
  458.  
  459.         case MOVING :
  460.                     instanceDrawing = YES;
  461.                     location = &(theEvent->location);
  462.                     [self display];
  463.                     break;
  464.         case DELETING :
  465.                     instanceDrawing = YES;
  466.                     location = &(theEvent->location);
  467.                     [self display];
  468.                     break;
  469.         case INSERTING :
  470.                     instanceDrawing = YES;
  471.                     location = &(theEvent->location);
  472.                     [self display];
  473.                     break;
  474.         default:     if(instanceDrawing) {
  475.                     instanceDrawing = NO;
  476.                     [self display];
  477.                 }
  478.                 break;
  479.     }
  480. }
  481.  
  482. - fixState:(NXEvent *)theEvent
  483. {
  484.     state = WAITING;
  485.     if (theEvent->flags&NX_ALPHASHIFTMASK)
  486.         state = DELETING;
  487.     if (theEvent->flags&NX_CONTROLMASK)
  488.         state = INSERTING;
  489.     if (theEvent->flags&NX_COMMANDMASK)
  490.         state = MOVING;
  491.     
  492.     switch (state) {
  493.         case DELETING : [inputMode setStringValue:"Deleting"]; break;
  494.         case INSERTING : [inputMode setStringValue:"Inserting"]; break;
  495.         case MOVING : [inputMode setStringValue:"Moving"]; break;
  496.         case WAITING : [inputMode setStringValue:"Waiting"]; break;
  497.         default : [inputMode setStringValue:"Barfing"]; break;
  498.     }
  499.     return self;
  500. }
  501.  
  502. - flagsChanged:(NXEvent *)theEvent
  503. {
  504.     if (theEvent->flags&NX_ALTERNATEMASK)
  505.         [inputPen setStringValue:"Up"];
  506.     else
  507.         [inputPen setStringValue:"Down"];
  508.     [self fixState:theEvent];
  509.     return self;
  510. }
  511. @end
  512.